package com.bn.feedMaster;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Set;

import com.bn.feedMaster.FeedErrorMessages;
import com.bn.feedMaster.FeedProcessException;

import atg.epub.project.Process;
import atg.epub.project.Project;
import atg.nucleus.GenericService;
import atg.process.action.ActionConstants;
import atg.process.action.ActionException;
import atg.repository.RepositoryItem;
import atg.security.ThreadSecurityManager;
import atg.workflow.ActorAccessException;
import atg.workflow.MissingWorkflowDescriptionException;
import atg.workflow.WorkflowConstants;
import atg.workflow.WorkflowManager;
import atg.workflow.WorkflowView;


/**
 * The Class FeedsTools.
 */
public class FeedsTools extends GenericService{

	/** The task list for auto publish. */
	private List<String> taskListForAutoPublish;

	/** The work flow tools. */
	private WorkFlowTools workFlowTools;

	/** The active auto publish. */
	private boolean activeAutoPublish;

	/** The workflow manager. */
	private WorkflowManager workflowManager;

	/** The work flow name for automatic public. */
	private String workFlowNameForAutomaticPublic;

	/** The work flow name. */
	private String workFlowName;

	/** The user name. */
	private String userName;
	
	   /** The Constant BCC_PROJECT_DATE_FORMAT. */
    private static final String BCC_PROJECT_DATE_FORMAT = "yyyy-MM-dd hh:mm:ss";
    

	
	
	/**
	 * Start project in bcc.
	 *
	 * @param fileName the file name
	 * @return the process
	 * @throws IOException Signals that an I/O exception has occurred.
	 * @throws FeedProcessException the feed process exception
	 * @throws Exception the exception
	 */
	public Process startProjectInBCC(String fileName) throws IOException, FeedProcessException,Exception {
		Process process = null;
			if (isLoggingDebug()) {
				logDebug("CatalogFeedProcessor.startProjectInBCC() method Started.");
			}
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					"yyyy-MM-dd hh:mm:ss");
			String dateString = simpleDateFormat.format(Calendar.getInstance()
					.getTime());
			String projectName = new StringBuilder().append("Feed_")
					.append(fileName).append("_").append(dateString).toString();
			// This workFlow will create the project in BCC
			if (isActiveAutoPublish()) {
				process = getWorkFlowTools().initiateWorkflow(projectName,
						getWorkFlowNameForAutomaticPublic(), getUserName());
			} else {
				process = getWorkFlowTools().initiateWorkflow(projectName,
						getWorkFlowName(), getUserName());
			}
			if (isLoggingDebug()) {
				logDebug("project created in BCC, project name :" + projectName);
			}
			if (isLoggingDebug()) {
				logDebug("CatalogFeedProcessor.startProjectInBCC() method Ended.");
			}
		return process;
	}
	
	/**
	 * Advance workflow.
	 *
	 * @param pProcess the process
	 * @throws MissingWorkflowDescriptionException the missing workflow description exception
	 * @throws ActorAccessException the actor access exception
	 * @throws UnsupportedOperationException the unsupported operation exception
	 * @throws ActionException the action exception
	 */
	public void advanceWorkflow(Process pProcess) throws MissingWorkflowDescriptionException, ActorAccessException, UnsupportedOperationException, ActionException {
		if (isLoggingInfo()) {
			logInfo("StoreLocatorFeedManager:advanceWorkflow():Started...");
		}
		RepositoryItem processWorkflow = pProcess.getProject().getWorkflow();
		String workflowProcessName = processWorkflow.getPropertyValue(
				"processName").toString();
		String subjectId = pProcess.getId();
			// an alternative would be to use the global workflow view at
			WorkflowView wv = getWorkflowManager().getWorkflowView(
					ThreadSecurityManager.currentUser());

			List<String> taskListId = getTaskListForAutoPublish();
			for (String taskId : taskListId) {
				if (isLoggingInfo()) {
					logInfo("Executing task: " + taskId);
				}
				wv.fireTaskOutcome(workflowProcessName,
						WorkflowConstants.DEFAULT_WORKFLOW_SEGMENT, subjectId,
						taskId, ActionConstants.ERROR_RESPONSE_DEFAULT);
			}
		if (isLoggingInfo()) {
			logInfo("StoreLocatorFeedManager:advanceWorkflow():Completed...");
		}
	}
	
	
	   /**
     * Start project in bcc.
     * 
     * @param errorsBuffer
     *            the errors buffer
     * @param feedName
     *            the feed name
     * @param config
     *            the config
     * @return the process
     * @throws FeedProcessException
     *             the feed process exception
     * @throws IOException
     *             Signals that an I/O exception has occurred.
     */
    public Process startProjectInBCC(StringBuilder errorsBuffer, String feedName)
            throws FeedProcessException, IOException {
        Process process = null;
        try {
            if (isLoggingDebug()) {
                logDebug("FeedsTools.startProjectInBCC() method Started.");
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(BCC_PROJECT_DATE_FORMAT);
            String dateString = simpleDateFormat.format(Calendar.getInstance().getTime());
            String projectName = new StringBuilder().append("Feed_").append(feedName).append("_")
                                                    .append(dateString).toString();
            // This workFlow will create the project in BCC
            if (isActiveAutoPublish()) {
                process = getWorkFlowTools().initiateWorkflow(projectName, getWorkFlowNameForAutomaticPublic(),
                                                              getUserName());
            } else {
                process = getWorkFlowTools().initiateWorkflow(projectName, getWorkFlowName(),
                                                              getUserName());
            }
            if (isLoggingDebug()) {
                logDebug("project created in BCC, project name :" + projectName);
            }
            if (isLoggingDebug()) {
                logDebug("FeedsTools.startProjectInBCC() method Ended.");
            }
        } catch (Exception e) {
            if (isLoggingError()) {
                logError("RepositoryException occured While processing the feed", e);
            }
            errorsBuffer.append("there are some errors while processing files and creating project" + e.getMessage()
                                + "\n");
            throw new FeedProcessException(FeedErrorMessages.FEEDPROCESS_EXCEPTION_MSG, e);
        }
        return process;
    }

    /**
     * Advance workflow.
     * 
     * @param pProcess
     *            the process
     * @param errorsBuffer
     *            the errors buffer
     * @param configuration
     *            the configuration
     */
    public void advanceWorkflow(Process pProcess, StringBuilder errorsBuffer) {
        if (isLoggingInfo()) {
            logInfo("Start FeedsTools.advanceWorkflow");
        }
        RepositoryItem processWorkflow = pProcess.getWorkflow();
        String workflowProcessName = processWorkflow.getPropertyValue("processName").toString();
        String subjectId = pProcess.getId();
        Project prj = pProcess.getProject();
        try {
             //Checking if project contains any assets or not
             Set dd = prj.getAssets();
             if(dd.isEmpty()){
                 if(isLoggingInfo()){
                     logInfo("Deleting project:"+prj.getDisplayName()+" as it does not conatin any assets");
                 }
                 //project is empty so deleting
                prj.delete(getUserName());
             }else{
                // an alternative would be to use the global workflow view at
                 WorkflowView wv = getWorkflowManager().getWorkflowView(ThreadSecurityManager.currentUser());

                 List<String> taskListId = getTaskListForAutoPublish();
                 for (String taskId : taskListId) {
                     if (isLoggingInfo()) {
                         logInfo("Executing task: " + taskId);
                     }
                     wv.fireTaskOutcome(workflowProcessName, WorkflowConstants.DEFAULT_WORKFLOW_SEGMENT, subjectId, taskId,
                                        ActionConstants.ERROR_RESPONSE_DEFAULT);
                 }
             }
        } catch (Exception e) {
            if (isLoggingError()) {
                logError("Error publishing the project: ", e);
            }
            errorsBuffer.append("Exception during automatic publish" + e);
        }
        if (isLoggingInfo()) {
            logInfo("End MasterFeedsProcessor.advanceWorkflow");
        }
    }
    
    
	
	/**
	 * Gets the task list for auto publish.
	 *
	 * @return the taskListForAutoPublish
	 */
	public List<String> getTaskListForAutoPublish() {
		return taskListForAutoPublish;
	}



	/**
	 * Sets the task list for auto publish.
	 *
	 * @param taskListForAutoPublish the taskListForAutoPublish to set
	 */
	public void setTaskListForAutoPublish(List<String> taskListForAutoPublish) {
		this.taskListForAutoPublish = taskListForAutoPublish;
	}



	/**
	 * Gets the work flow tools.
	 *
	 * @return the workFlowTools
	 */
	public WorkFlowTools getWorkFlowTools() {
		return workFlowTools;
	}



	/**
	 * Sets the work flow tools.
	 *
	 * @param workFlowTools the workFlowTools to set
	 */
	public void setWorkFlowTools(WorkFlowTools workFlowTools) {
		this.workFlowTools = workFlowTools;
	}



	/**
	 * Checks if is active auto publish.
	 *
	 * @return the activeAutoPublish
	 */
	public boolean isActiveAutoPublish() {
		return activeAutoPublish;
	}



	/**
	 * Sets the active auto publish.
	 *
	 * @param activeAutoPublish the activeAutoPublish to set
	 */
	public void setActiveAutoPublish(boolean activeAutoPublish) {
		this.activeAutoPublish = activeAutoPublish;
	}



	/**
	 * Gets the workflow manager.
	 *
	 * @return the workflowManager
	 */
	public WorkflowManager getWorkflowManager() {
		return workflowManager;
	}



	/**
	 * Sets the workflow manager.
	 *
	 * @param workflowManager the workflowManager to set
	 */
	public void setWorkflowManager(WorkflowManager workflowManager) {
		this.workflowManager = workflowManager;
	}



	/**
	 * Gets the work flow name for automatic public.
	 *
	 * @return the workFlowNameForAutomaticPublic
	 */
	public String getWorkFlowNameForAutomaticPublic() {
		return workFlowNameForAutomaticPublic;
	}



	/**
	 * Sets the work flow name for automatic public.
	 *
	 * @param workFlowNameForAutomaticPublic the workFlowNameForAutomaticPublic to set
	 */
	public void setWorkFlowNameForAutomaticPublic(
			String workFlowNameForAutomaticPublic) {
		this.workFlowNameForAutomaticPublic = workFlowNameForAutomaticPublic;
	}



	/**
	 * Gets the work flow name.
	 *
	 * @return the workFlowName
	 */
	public String getWorkFlowName() {
		return workFlowName;
	}



	/**
	 * Sets the work flow name.
	 *
	 * @param workFlowName the workFlowName to set
	 */
	public void setWorkFlowName(String workFlowName) {
		this.workFlowName = workFlowName;
	}



	/**
	 * Gets the user name.
	 *
	 * @return the userName
	 */
	public String getUserName() {
		return userName;
	}



	/**
	 * Sets the user name.
	 *
	 * @param userName the userName to set
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}
}
